package com.liu.project.config;


import com.liu.project.filter.JwtAuthenticationFilter;
import com.liu.project.service.impl.AuthService;
import com.liu.project.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.servlet.Filter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
     AuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
     LogoutSuccessHandler logoutSuccessHandler;
    @Autowired
     AuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
      AuthService authService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
     AccessDeniedHandler accessDeniedHandler;


    //授权
   //链式编程
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人可以访问，功能也只有对应有权限的人才能访问
        //请求授权的规则

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.authorizeRequests()
                .antMatchers("/api/auth/**",
                        "/authentications/**",
                        // swagger资源要放行。
                        "/v2/api-docs",
                        "/swagger-resources",
                        "/swagger-resources/**",
                        "/configuration/ui",
                        "/configuration/security",
                        "/swagger-ui.html/**",
                        "/webjars/**"

                ).permitAll()
                .antMatchers("/api/**").authenticated()
                .anyRequest().permitAll();//AuthApiController
//        .antMatchers("/*").permitAll();

        //没有权限默认会转到登录页面，需要开启登录的页面


        http.formLogin()
                //.loginPage("/authentications/login")
                 .loginProcessingUrl("/api/auth/login")
                //.successForwardUrl("/api/auth//login-success")
              .successHandler(authenticationSuccessHandler)
               // .successForwardUrl("/api/auth/login-success")
                .failureHandler(authenticationFailureHandler)
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .accessDeniedHandler(accessDeniedHandler);

//                 .successForwardUrl("/api/auth/login-success")//登录成功地跳转路径
//                 .failureForwardUrl("/api/auth/login-failure");//失败路径

        http.logout()
                .logoutUrl("/api/auth/logout")
                .logoutSuccessHandler(logoutSuccessHandler);
//                .logoutSuccessUrl("/api/auto/logout-success");
       http.headers().cacheControl();//禁用缓存
        http.addFilterBefore(new JwtAuthenticationFilter(redisUtil), UsernamePasswordAuthenticationFilter.class);

        //防止网站工具
        http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求

        //开启记住我功能 实际是cookie 浏览器默认保存两周
        //定制记住我的参数
        http.rememberMe().rememberMeParameter("remember");//login.html


    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(authService).passwordEncoder(new BCryptPasswordEncoder());

    }


    @Bean
    public CorsFilter corsFilter() {
        //创建CorsConfiguration 对象后添加配置
        CorsConfiguration configuration = new CorsConfiguration();
        //设置放行那些原始域
        configuration.addAllowedOriginPattern("/*");
//        configuration.addAllowedOriginPattern("http://localhost:8080");
        //放行那些原始请求头部信息
        configuration.addAllowedHeader("/*");
        //放行那些请求  *代表所有
        configuration.addAllowedMethod("/*");
        //是否允许发送Cookie，必须开启，因为我们的JSESSIONID需要在Cookie中携带
        configuration.setAllowCredentials(true);
        //映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", configuration);
        //返回CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }

}
